▍ humdrum codex / glint v1.1.2
license AGPL-3.0
4.5 KB raw
id
TASK-035
title
Copy rich text to clipboard (Ctrl+R)
status
🟢 In progress
assignee
created_date
2026-07-01 02:02
updated_date
2026-07-01 02:54
labels
feature
dependencies
priority
medium
ordinal
34000

Description

User-validated need: selecting rendered preview text with the mouse (TASK-034, done) and Cmd+C now works mechanically, but the pasted result is ugly — glamour's terminal rendering includes box-drawing chars, ANSI padding, and other terminal-only artifacts, not clean formatted text. A dedicated 'copy rich text' action is needed instead: convert the buffer's markdown to real formatted content (bold/headings/lists/links) and put it on the system clipboard, so pasting into Mail/Word/Docs/Pages/Slack shows proper formatting.

Reuse the existing internal/export HTML pipeline (Document()/renderBody(), same as Ctrl+E/-e, TASK-030/021) as the source of truth for formatting, then convert HTML->RTF. On macOS: shell out to 'textutil -convert rtf' for the HTML->RTF conversion, then use osascript to set the pasteboard with BOTH flavors at once — «class RTF» (rich) and string (the raw markdown as plain-text fallback) — via 'set the clipboard to {«class RTF»:rtfData, string:plainText}'. Setting both flavors matters: apps that support rich paste (Mail, Word, Pages, Slack) pick the RTF automatically, while anything that doesn't falls back to plain text instead of getting nothing or gibberish. Plain atotto/clipboard.WriteAll (already used for Ctrl+C/V) only ever sets the plain-text flavor, so it can't do this alone.

Non-macOS: return a clear 'unsupported' error rather than silently writing plain text only, matching the earlier design note from the archived RTF-export task.

Trigger: new in-app keybind Ctrl+R (unused — current bindings are C/D/E/F/G/K/L/N/P/Q/S/T/U/V/W/X/Y/Z/Q, per internal/help/help.go), plus a headless CLI flag (-R / --copy-rich ) mirroring the -e/--export pattern (TASK-030) for scripting (Raycast/Alfred/automation).

Acceptance Criteria

Implementation Notes

Implemented: internal/export/rtf.go (CopyRichText/htmlToRTF/setClipboardRichText), Ctrl+R keybind + copyRichText() in app.go, -R/--copy-rich CLI flag in main.go, help.go docs. Real bug found+fixed during manual verification: AppleScript's classic 'set the clipboard to {«class RTF»:x, string:y}' record form LOOKED right in 'clipboard info' but real readers (pbpaste, a second-process NSPasteboard read) only ever got the plain-text flavor back -- rewrote setClipboardRichText to use JXA (osascript -l JavaScript) calling NSPasteboard.setDataForType directly with public.rtf / public.utf8-plain-text, which verified correctly via direct NSPasteboard read-back (byte-exact RTF content, correct plain fallback). Note: pbpaste -Prefer rtf itself is unreliable on this macOS version (always prefers plain text if present, contradicting its own man page) -- not a signal to trust; verify via a real GUI paste instead. AC#1,4,6,7 verified by code+tests. AC#2's clipboard-flavor mechanics verified headlessly (NSPasteboard read-back matches source RTF byte-for-byte); the visual 'paste into TextEdit/Mail/Word looks right' half and AC#3's in-app Ctrl+R still need a human to actually press the key and paste somewhere -- can't drive that from here. AC#5 (non-macOS error) is a one-line runtime.GOOS check, untested per-branch (same convention as the existing browserCommand GOOS-switch).